package my.assistant.homecashmanager.tally.web;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import my.assistant.homecashmanager.account.data.AccountBase;
import my.assistant.homecashmanager.common.data.MoneyType;
import my.assistant.homecashmanager.inoutitem.data.DmInoutItem;
import my.assistant.homecashmanager.inoutitem.domain.DmInoutItemDomain;
import my.assistant.homecashmanager.tally.data.JournalAccount;
import my.assistant.homecashmanager.tally.domain.TallyDomain;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.assistant.common.exception.GetFromDBException;
import org.assistant.common.exception.ImplementNotFoundException;
import org.assistant.common.exception.SaveIntoDBException;
import org.assistant.common.utils.ClassUtils;
import org.assistant.common.utils.DateUtils;
import org.assistant.common.web.servlet.mvc.Controller;
import org.assistant.common.web.servlet.mvc.DataType;
import org.assistant.common.web.servlet.mvc.Page;
import org.assistant.common.web.servlet.mvc.ResultData;
import org.assistant.csp.data.Global;
import org.assistant.csp.data.RelationUser;
import org.assistant.csp.data.UserSession;
import org.assistant.csp.domain.UserDomain;

public class TallyController extends Controller {
	private static final long serialVersionUID = 6369375910282601003L;
	private static final Log log = LogFactory.getLog(TallyController.class);
	private static final boolean isDebugEnabled = log.isDebugEnabled();

	private TallyDomain tallyDomain;
	private DmInoutItemDomain dmInoutItemDomain;
	private UserDomain userDomain;

	public TallyController() throws ImplementNotFoundException {
		tallyDomain = ClassUtils.getInterfaceImplement(TallyDomain.class);
		dmInoutItemDomain = ClassUtils
			.getInterfaceImplement(DmInoutItemDomain.class);
		userDomain = ClassUtils.getInterfaceImplement(UserDomain.class);
	}

	protected Object requestDispatcher(HttpServletRequest request,
			HttpServletResponse response, String methodName) {
		try {
			if ("get".equals(methodName)) {
				return get(request, response);
			} else if ("save".equals(methodName)) {
				return save(request, response);
			} else {
				return index(request, response);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 显示收支流水账首页
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public Page index(HttpServletRequest request, HttpServletResponse response) {
		UserSession userSession = (UserSession) request
			.getSession().getAttribute(Global.CURRENT_USER);

		String homeId = userSession.getHomeId();

		// 获取页面上收支项目下拉框里的数据
		List<DmInoutItem> dmInoutItemList = null;
		try {
			dmInoutItemList = dmInoutItemDomain.getDmInoutItemByHome(homeId);
		} catch (GetFromDBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 获取页面上收支账户下拉框里的数据
		Map<String, AccountBase> accountMap = userSession
			.getCacheInSession().getCacheAccountMap();

		// 获取页面上关联人员下拉框里的数据
		List<RelationUser> relationUserList = null;
		try {
			relationUserList = userDomain.getRelationUserByHome(homeId);
		} catch (GetFromDBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		request.setAttribute("dmInoutItemList", dmInoutItemList);
		request.setAttribute("accountMap", accountMap);
		request.setAttribute("relationUserList", relationUserList);

		return new Page("/my/assistant/homecashmanager/tally/IndexTally.jsp");
	}

	public ResultData<?> get(HttpServletRequest request,
			HttpServletResponse response) {
		ResultData<String> resultData = new ResultData<String>();

		List<JournalAccount> list = null;
		try {
			list = this.tallyDomain.getJournalAccountList();
		} catch (GetFromDBException e) {
			e.printStackTrace();
			resultData.setException(e.getMessage());
			return resultData;
		}

		UserSession userSession = (UserSession) request
			.getSession().getAttribute(Global.CURRENT_USER);
		Map<String, AccountBase> cacheAccountMap = userSession
			.getCacheInSession().getCacheAccountMap();

		StringBuffer buff = new StringBuffer();
		buff.append("{");
		buff.append("total:'").append(list.size()).append("',");
		buff.append("page:'").append(1).append("',");
		buff.append("records:'").append(list.size()).append("',");
		buff.append("rows:[");
		for (int i = 0; i < list.size(); i++) {
			JournalAccount ja = list.get(i);
			if (i > 0) {
				buff.append(",");
			}
			buff.append("{");
			buff.append("id:'").append(ja.getId()).append("',");
			buff.append("cell:[");
			buff.append("'").append(ja.getId()).append("',");

			String dealDate = DateUtils.toString(ja.getDealDate());
			buff.append("'").append(dealDate).append("',");

			buff.append("'").append(ja.getInoutItemId()).append("',");
			buff.append("'").append(ja.getInoutItemName()).append("',");
			buff.append("'").append(ja.getInoutItemType()).append("',");

			String outAccountId = ja.getOutAccountId();
			outAccountId = (outAccountId == null ? "" : outAccountId);
			buff.append("'").append(outAccountId).append("',");

			AccountBase outAccount = cacheAccountMap.get(ja.getOutAccountId());
			String outAccountName = "";
			if (null == outAccount) {
				outAccountName = "";
			} else {
				outAccountName = outAccount.getName();
			}
			buff.append("'").append(outAccountName).append("',");

			String inAccountId = ja.getInAccountId();
			inAccountId = (inAccountId == null ? "" : inAccountId);
			buff.append("'").append(inAccountId).append("',");

			AccountBase inAccount = cacheAccountMap.get(ja.getInAccountId());
			String inAccountName = "";
			if (null == inAccount) {
				inAccountName = "";
			} else {
				inAccountName = inAccount.getName();
			}
			buff.append("'").append(inAccountName).append("',");

			buff.append("'").append(ja.getMoney()).append("',");

			String moneyType = ja.getMoneyType();
			moneyType = MoneyType.getName(moneyType);
			buff.append("'").append(moneyType).append("',");

			buff.append("'").append(ja.getMemo()).append("',");
			buff.append("'").append(ja.getRelationUserId()).append("',");
			buff.append("'").append(ja.getRelationUserName()).append("',");
			buff.append("'").append(ja.getLogUserName()).append("'");
			buff.append("]");
			buff.append("}");
		}
		buff.append("]");
		buff.append("}");

		resultData.setData(buff.toString());
		resultData.setType(DataType.original_json);

		return resultData;
	}

	public ResultData<?> save(HttpServletRequest request,
			HttpServletResponse response) {
		String t = request.getParameter("t");// 获取操作类型

		// 根据不同的操作类型选择相应的函数进行处理
		if ("in".equals(t)) {// 收入
			return saveIn(request, response);
		} else if ("out".equals(t)) {// 支出
			return saveOut(request, response);
		} else if ("access".equals(t)) {// 存取款
			return saveAccess(request, response);
		} else if ("transfer".equals(t)) {// 转账
			return saveTransfer(request, response);
		}

		return null;
	}

	/**
	 * 保存（增加或更新）一条收入账
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	private ResultData<?> saveIn(HttpServletRequest request,
			HttpServletResponse response) {
		ResultData<String> resultData = new ResultData<String>();

		String id = request.getParameter("in_id");
		String strDealDate = request.getParameter("in_dealDate");
		Date dealDate = null;
		try {
			dealDate = DateUtils.parse(strDealDate);
		} catch (ParseException e1) {
			e1.printStackTrace();
			resultData.setException(e1.getMessage());
			return resultData;
		}
		String strInoutItemId = request.getParameter("in_inoutItem");
		long inoutItemId = Long.parseLong(strInoutItemId);
		String strInMoney = request.getParameter("in_money");
		BigDecimal inMoney = new BigDecimal(strInMoney);
		String inAccountId = request.getParameter("in_account");
		String relationUserId = request.getParameter("in_relationUser");
		String memo = request.getParameter("in_memo");

		UserSession userSession = (UserSession) request
			.getSession().getAttribute(Global.CURRENT_USER);
		Map<String, AccountBase> cacheAccountMap = userSession
			.getCacheInSession().getCacheAccountMap();
		AccountBase account = cacheAccountMap.get(inAccountId);

		String moneyType = "01";// 币种，默认为人民币
		if (account != null) {
			moneyType = account.getMoneyType();// 获取账户的币种，并将该条收支记录的币种设置为账户的币种
		}

		JournalAccount journalAccount = new JournalAccount();
		journalAccount.setId(id);
		journalAccount.setDealDate(dealDate);
		journalAccount.setDataFrom("0");// 数据来自于本网站
		journalAccount.setInoutItemId(inoutItemId);
		journalAccount.setMoney(inMoney);
		journalAccount.setMoneyType(moneyType);
		journalAccount.setInAccountId(inAccountId);
		journalAccount.setRelationUserId(relationUserId);
		journalAccount.setMemo(memo);
		journalAccount.setLogUserId(userSession.getId());
		journalAccount.setLogUserName(userSession.getName());
		journalAccount.setLogUserHomeId(userSession.getHomeId());
		try {
			if (null == id || "-1".equals(id) || "".equals(id.trim())) {// 增加
				this.tallyDomain.insertJournalAccount(journalAccount);
				resultData.putUserData("flag", "insert");
			} else {// 更新
				this.tallyDomain.updateJournalAccount(journalAccount);
				resultData.putUserData("flag", "update");
			}
			resultData.putUserData("id", journalAccount.getId());
			resultData.putUserData("logUserId", journalAccount.getLogUserId());
			resultData.putUserData("logUserName", journalAccount
				.getLogUserName());
			resultData.putUserData("moneyType", MoneyType.getName(moneyType));
		} catch (SaveIntoDBException e) {
			e.printStackTrace();
			resultData.setException(e.getMessage());
			return resultData;
		}

		resultData.setMessage("保存成功！");

		return resultData;
	}

	/**
	 * 保存（增加或更新）一条支出账
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	private ResultData<?> saveOut(HttpServletRequest request,
			HttpServletResponse response) {
		ResultData<String> resultData = new ResultData<String>();

		String id = request.getParameter("out_id");
		String strDealDate = request.getParameter("out_dealDate");
		Date dealDate = null;
		try {
			dealDate = DateUtils.parse(strDealDate);
		} catch (ParseException e1) {
			e1.printStackTrace();
			resultData.setException(e1.getMessage());
			return resultData;
		}
		String strInoutItemId = request.getParameter("out_inoutItem");
		long inoutItemId = Long.parseLong(strInoutItemId);
		String strOutMoney = request.getParameter("out_money");
		BigDecimal outMoney = new BigDecimal(strOutMoney);
		String outAccountId = request.getParameter("out_account");
		String relationUserId = request.getParameter("out_relationUser");
		String memo = request.getParameter("out_memo");

		UserSession userSession = (UserSession) request
			.getSession().getAttribute(Global.CURRENT_USER);
		Map<String, AccountBase> cacheAccountMap = userSession
			.getCacheInSession().getCacheAccountMap();
		AccountBase account = cacheAccountMap.get(outAccountId);

		String moneyType = "01";// 币种，默认为人民币
		if (account != null) {
			moneyType = account.getMoneyType();// 获取账户的币种，并将该条收支记录的币种设置为账户的币种
		}

		JournalAccount journalAccount = new JournalAccount();
		journalAccount.setId(id);
		journalAccount.setDealDate(dealDate);
		journalAccount.setDataFrom("0");// 数据来自于本网站
		journalAccount.setInoutItemId(inoutItemId);
		journalAccount.setMoney(outMoney);
		journalAccount.setMoneyType(moneyType);
		journalAccount.setOutAccountId(outAccountId);
		journalAccount.setRelationUserId(relationUserId);
		journalAccount.setMemo(memo);
		journalAccount.setLogUserId(userSession.getId());
		journalAccount.setLogUserName(userSession.getName());
		journalAccount.setLogUserHomeId(userSession.getHomeId());
		try {
			if (null == id || "-1".equals(id) || "".equals(id.trim())) {// 增加
				this.tallyDomain.insertJournalAccount(journalAccount);
				resultData.putUserData("flag", "insert");
			} else {// 更新
				this.tallyDomain.updateJournalAccount(journalAccount);
				resultData.putUserData("flag", "update");
			}
			resultData.putUserData("id", journalAccount.getId());
			resultData.putUserData("logUserId", journalAccount.getLogUserId());
			resultData.putUserData("logUserName", journalAccount
				.getLogUserName());
			resultData.putUserData("moneyType", MoneyType.getName(moneyType));
		} catch (SaveIntoDBException e) {
			e.printStackTrace();
			resultData.setException(e.getMessage());
			return resultData;
		}

		resultData.setMessage("保存成功！");

		return resultData;
	}

	/**
	 * 保存（增加或更新）一条存取款账
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	private ResultData<?> saveAccess(HttpServletRequest request,
			HttpServletResponse response) {
		ResultData<String> resultData = new ResultData<String>();

		String id = request.getParameter("access_id");
		String strDealDate = request.getParameter("access_dealDate");
		Date dealDate = null;
		try {
			dealDate = DateUtils.parse(strDealDate);
		} catch (ParseException e1) {
			e1.printStackTrace();
			resultData.setException(e1.getMessage());
			return resultData;
		}
		String strInoutItemId = request.getParameter("access_inoutItem");
		strInoutItemId = (strInoutItemId == null ? "1" : strInoutItemId.trim());
		long inoutItemId = Long.parseLong(strInoutItemId);
		String strOutMoney = request.getParameter("access_money");
		BigDecimal outMoney = new BigDecimal(strOutMoney);
		String cashAccountId = request.getParameter("access_cash_account");
		String bankAccountId = request.getParameter("access_bank_account");
		String relationUserId = request.getParameter("access_relationUser");
		String memo = request.getParameter("access_memo");

		UserSession userSession = (UserSession) request
			.getSession().getAttribute(Global.CURRENT_USER);
		Map<String, AccountBase> cacheAccountMap = userSession
			.getCacheInSession().getCacheAccountMap();
		AccountBase bankAccount = cacheAccountMap.get(bankAccountId);

		String moneyType = "01";// 币种，默认为人民币
		if (bankAccount != null) {
			moneyType = bankAccount.getMoneyType();// 获取账户的币种，并将该条收支记录的币种设置为账户的币种
		}

		JournalAccount journalAccount = new JournalAccount();
		journalAccount.setId(id);
		journalAccount.setDealDate(dealDate);
		journalAccount.setDataFrom("0");// 数据来自于本网站
		journalAccount.setInoutItemId(inoutItemId);
		journalAccount.setMoney(outMoney);
		journalAccount.setMoneyType(moneyType);

		String inAccountId = null, outAccountId = null;
		if (inoutItemId == 1) {// 取款
			inAccountId = cashAccountId;
			outAccountId = bankAccountId;
		} else if (inoutItemId == 2) {// 存款
			inAccountId = bankAccountId;
			outAccountId = cashAccountId;
		}
		journalAccount.setInAccountId(inAccountId);
		journalAccount.setOutAccountId(outAccountId);

		journalAccount.setRelationUserId(relationUserId);
		journalAccount.setMemo(memo);
		journalAccount.setLogUserId(userSession.getId());
		journalAccount.setLogUserName(userSession.getName());
		journalAccount.setLogUserHomeId(userSession.getHomeId());
		try {
			if (null == id || "-1".equals(id) || "".equals(id.trim())) {// 增加
				this.tallyDomain.insertJournalAccount(journalAccount);
				resultData.putUserData("flag", "insert");
			} else {// 更新
				this.tallyDomain.updateJournalAccount(journalAccount);
				resultData.putUserData("flag", "update");
			}
			resultData.putUserData("id", journalAccount.getId());
			resultData.putUserData("logUserId", journalAccount.getLogUserId());
			resultData.putUserData("logUserName", journalAccount
				.getLogUserName());
			resultData.putUserData("moneyType", MoneyType.getName(moneyType));
		} catch (SaveIntoDBException e) {
			e.printStackTrace();
			resultData.setException(e.getMessage());
			return resultData;
		}

		resultData.setMessage("保存成功！");

		return resultData;
	}

	private ResultData<?> saveTransfer(HttpServletRequest request,
			HttpServletResponse response) {
		ResultData<String> resultData = new ResultData<String>();

		String id = request.getParameter("transfer_id");
		String strDealDate = request.getParameter("transfer_dealDate");
		Date dealDate = null;
		try {
			dealDate = DateUtils.parse(strDealDate);
		} catch (ParseException e1) {
			e1.printStackTrace();
			resultData.setException(e1.getMessage());
			return resultData;
		}
		String strInoutItemId = request.getParameter("transfer_inoutItem");
		strInoutItemId = (strInoutItemId == null ? "3" : strInoutItemId.trim());
		long inoutItemId = Long.parseLong(strInoutItemId);
		String strOutMoney = request.getParameter("transfer_money");
		BigDecimal outMoney = new BigDecimal(strOutMoney);
		String outAccountId = request.getParameter("transfer_out_account");
		String inAccountId = request.getParameter("transfer_in_account");
		String relationUserId = request.getParameter("transfer_relationUser");
		String memo = request.getParameter("transfer_memo");

		UserSession userSession = (UserSession) request
			.getSession().getAttribute(Global.CURRENT_USER);
		Map<String, AccountBase> cacheAccountMap = userSession
			.getCacheInSession().getCacheAccountMap();
		AccountBase outAccount = cacheAccountMap.get(outAccountId);

		String moneyType = "01";// 币种，默认为人民币
		if (outAccount != null) {
			moneyType = outAccount.getMoneyType();// 获取账户的币种，并将该条收支记录的币种设置为账户的币种
		}

		JournalAccount journalAccount = new JournalAccount();
		journalAccount.setId(id);
		journalAccount.setDealDate(dealDate);
		journalAccount.setDataFrom("0");// 数据来自于本网站
		journalAccount.setInoutItemId(inoutItemId);
		journalAccount.setMoney(outMoney);
		journalAccount.setMoneyType(moneyType);

		journalAccount.setInAccountId(inAccountId);
		journalAccount.setOutAccountId(outAccountId);

		journalAccount.setRelationUserId(relationUserId);
		journalAccount.setMemo(memo);
		journalAccount.setLogUserId(userSession.getId());
		journalAccount.setLogUserName(userSession.getName());
		journalAccount.setLogUserHomeId(userSession.getHomeId());
		try {
			if (null == id || "-1".equals(id) || "".equals(id.trim())) {// 增加
				this.tallyDomain.insertJournalAccount(journalAccount);
				resultData.putUserData("flag", "insert");
			} else {// 更新
				this.tallyDomain.updateJournalAccount(journalAccount);
				resultData.putUserData("flag", "update");
			}
			resultData.putUserData("id", journalAccount.getId());
			resultData.putUserData("logUserId", journalAccount.getLogUserId());
			resultData.putUserData("logUserName", journalAccount
				.getLogUserName());
			resultData.putUserData("moneyType", MoneyType.getName(moneyType));
		} catch (SaveIntoDBException e) {
			e.printStackTrace();
			resultData.setException(e.getMessage());
			return resultData;
		}

		resultData.setMessage("保存成功！");

		return resultData;
	}
}
